#include<iostream>
#include <sys/types.h>        
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <string>
using namespace std;


class Tcp_client
{
public:
    Tcp_client(int port, string ip)
        :_sockfd(-1)
        ,_server_port(port)
        ,_server_ip(ip)
    {}

    void Tcp_client_init()
    {
        _sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if(_sockfd < 0)
        {
            cerr << "socket error!" << endl;
            exit(2);
        }
    }

    void Request()
    {
        string msg;
        char buff[1024];
        while(true)
        {
            cout << "Please Enter!" << endl;
            getline(cin, msg);

            write(_sockfd, msg.c_str(), msg.size());

            ssize_t s = read(_sockfd, buff, sizeof(buff)-1);
            if(s > 0)
            {
                buff[s] = '\0';
                cout << "server echo# " << buff << endl;
            }
            else if(s == 0)
            {
                cout << "server close!" << endl;
                break;
            }
            else
            {
                cout << "server read error!" << endl;
                break;
            }
        }
    }

    void Start()
    {
        struct sockaddr_in peer;
        memset(&peer, '\0', sizeof(peer));
        peer.sin_family = AF_INET;
        peer.sin_port = htons(_server_port);
        peer.sin_addr.s_addr = inet_addr(_server_ip.c_str());

        //客户端发起连接请求;
        int ret = connect(_sockfd, (sockaddr*)&peer, sizeof(peer));
        if(ret == 0)
        {
            cout << "connect success!" << endl;
            //连接请求成功; 这里实现简单的回声;
            Request();
        }
        else
        {
            cerr << "connect error!" << endl;
            exit(3);
        }
    }

    ~Tcp_client()
    {
        if(_sockfd > 0)
            close(_sockfd);
    }

private:
    int _sockfd;
    int _server_port;
    string _server_ip;
};

void Usage(std::string proc)
{
	std::cout << "Usage: " << proc << "server_ip server_port" << std::endl;
}

int main(int argc, char* argv[])
{
    if(argc != 3)
    {
        Usage(argv[0]);
        return 1;
    }

    std::string server_ip = argv[1];
	int server_port = atoi(argv[2]);
	Tcp_client* clt = new Tcp_client(server_port, server_ip);
	clt->Tcp_client_init();
	clt->Start();
    return 0;
}